package cn.metona.mq.utils;

import cn.metona.mq.MQToolkit;
import cn.metona.mq.core.MessageQueue;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Objects;
import java.util.logging.Logger;

/**
 * 监控工具类
 * 提供队列监控和统计功能
 */
public class MonitorUtils {
    private static final Logger logger = Logger.getLogger(MonitorUtils.class.getName());
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 打印所有队列统计信息（中文版）
     */
    public static void printAllQueueStats() {
        System.out.println("=== 消息队列统计信息 ===");
        System.out.println("报告时间: " + LocalDateTime.now().format(FORMATTER));
        System.out.println("--------------------------------------------------");

        MessageQueue.QueueStats[] stats = MQToolkit.getAllQueueStats();
        if (stats == null || stats.length == 0) {
            System.out.println("未找到任何队列。");
            return;
        }

        System.out.printf("%-20s | %-8s | %-6s | %-6s | %-6s%n",
                "队列名称", "消息数", "消费者", "运行中", "已暂停");
        System.out.println("--------------------------------------------------");

        Arrays.stream(stats).forEach(stat -> {
            if (stat != null) {
                System.out.printf("%-20s | %-8d | %-6d | %-6s | %-6s%n",
                        stat.getQueueName(),
                        stat.getMessageCount(),
                        stat.getConsumerCount(),
                        stat.isRunning() ? "是" : "否",
                        stat.isPaused() ? "是" : "否");
            }
        });

        System.out.println("--------------------------------------------------");
        System.out.println("总队列数: " + stats.length);
        long totalMessages = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getMessageCount)
                .sum();
        System.out.println("总消息数: " + totalMessages);
        System.out.println("===============================================");
    }

    /**
     * 打印指定队列统计信息（中文版）
     */
    public static void printQueueStats(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            System.out.println("无效的队列名称");
            return;
        }

        MessageQueue.QueueStats stats = MQToolkit.getQueueStats(queueName);
        if (stats == null) {
            System.out.println("未找到队列: " + queueName);
            return;
        }

        System.out.println("=== 队列统计信息: " + queueName + " ===");
        System.out.println("报告时间: " + LocalDateTime.now().format(FORMATTER));
        System.out.println("--------------------------------------------------");
        System.out.printf("消息数量:     %d%n", stats.getMessageCount());
        System.out.printf("消费者数:     %d%n", stats.getConsumerCount());
        System.out.printf("运行状态:     %s%n", stats.isRunning() ? "运行中" : "已停止");
        System.out.printf("暂停状态:     %s%n", stats.isPaused() ? "已暂停" : "正常");
        System.out.printf("已处理消息:   %d%n", stats.getProcessedCount());
        System.out.printf("失败消息:     %d%n", stats.getFailedCount());
        if (stats.getProcessedCount() + stats.getFailedCount() > 0) {
            double successRate = (double) stats.getProcessedCount() /
                    (stats.getProcessedCount() + stats.getFailedCount()) * 100;
            System.out.printf("成功率:       %.2f%%%n", successRate);
        }
        System.out.println("===============================================");
    }

    /**
     * 获取系统健康状态
     */
    public static SystemHealth getSystemHealth() {
        MessageQueue.QueueStats[] stats = MQToolkit.getAllQueueStats();
        if (stats == null) {
            return new SystemHealth(0, 0, 0, 0, 0, 0);
        }

        long totalQueues = stats.length;
        long totalMessages = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getMessageCount)
                .sum();
        long runningQueues = Arrays.stream(stats)
                .filter(s -> s != null && s.isRunning())
                .count();
        long pausedQueues = Arrays.stream(stats)
                .filter(s -> s != null && s.isPaused())
                .count();
        long totalProcessed = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getProcessedCount)
                .sum();
        long totalFailed = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getFailedCount)
                .sum();

        return new SystemHealth(totalQueues, totalMessages, runningQueues, pausedQueues, totalProcessed, totalFailed);
    }

    /**
     * 系统健康状态类
     */
    public static class SystemHealth {
        private final long totalQueues;
        private final long totalMessages;
        private final long runningQueues;
        private final long pausedQueues;
        private final long totalProcessed;
        private final long totalFailed;

        public SystemHealth(long totalQueues, long totalMessages, long runningQueues,
                            long pausedQueues, long totalProcessed, long totalFailed) {
            this.totalQueues = totalQueues;
            this.totalMessages = totalMessages;
            this.runningQueues = runningQueues;
            this.pausedQueues = pausedQueues;
            this.totalProcessed = totalProcessed;
            this.totalFailed = totalFailed;
        }

        public long getTotalQueues() { return totalQueues; }
        public long getTotalMessages() { return totalMessages; }
        public long getRunningQueues() { return runningQueues; }
        public long getPausedQueues() { return pausedQueues; }
        public long getTotalProcessed() { return totalProcessed; }
        public long getTotalFailed() { return totalFailed; }

        public boolean isHealthy() {
            return totalQueues > 0 && runningQueues > 0;
        }

        public double getSuccessRate() {
            long total = totalProcessed + totalFailed;
            if (total == 0) {
                return 1.0;
            }
            return (double) totalProcessed / total;
        }
    }

    /**
     * 打印系统健康状态（中文版）
     */
    public static void printSystemHealth() {
        SystemHealth health = getSystemHealth();
        System.out.println("=== 系统健康报告 ===");
        System.out.println("报告时间: " + LocalDateTime.now().format(FORMATTER));
        System.out.println("--------------------------------------------------");
        System.out.printf("总队列数:     %d%n", health.getTotalQueues());
        System.out.printf("运行中队列:   %d%n", health.getRunningQueues());
        System.out.printf("已暂停队列:   %d%n", health.getPausedQueues());
        System.out.printf("总消息数:     %d%n", health.getTotalMessages());
        System.out.printf("已处理消息:   %d%n", health.getTotalProcessed());
        System.out.printf("失败消息:     %d%n", health.getTotalFailed());
        System.out.printf("成功率:       %.2f%%%n", health.getSuccessRate() * 100);
        System.out.printf("系统状态:     %s%n", health.isHealthy() ? "健康" : "不健康");
        System.out.println("===============================================");
    }

    /**
     * 打印详细的队列性能报告（中文版）
     */
    public static void printDetailedPerformanceReport() {
        System.out.println("=== 详细性能报告 ===");
        System.out.println("报告时间: " + LocalDateTime.now().format(FORMATTER));
        System.out.println("--------------------------------------------------");

        MessageQueue.QueueStats[] stats = MQToolkit.getAllQueueStats();
        if (stats == null || stats.length == 0) {
            System.out.println("未找到任何队列。");
            return;
        }

        System.out.printf("%-20s | %-8s | %-8s | %-8s | %-8s | %-8s%n",
                "队列名称", "当前消息", "已处理", "失败", "消费者", "成功率");
        System.out.println("--------------------------------------------------");

        Arrays.stream(stats).forEach(stat -> {
            if (stat != null) {
                long totalProcessed = stat.getProcessedCount();
                long totalFailed = stat.getFailedCount();
                long totalOperations = totalProcessed + totalFailed;
                double successRate = totalOperations > 0 ?
                        (double) totalProcessed / totalOperations * 100 : 100.0;

                System.out.printf("%-20s | %-8d | %-8d | %-8d | %-8d | %7.2f%%%n",
                        stat.getQueueName(),
                        stat.getMessageCount(),
                        totalProcessed,
                        totalFailed,
                        stat.getConsumerCount(),
                        successRate);
            }
        });

        System.out.println("--------------------------------------------------");
        System.out.println("系统总体统计:");
        long totalMessages = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getMessageCount)
                .sum();
        long totalProcessed = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getProcessedCount)
                .sum();
        long totalFailed = Arrays.stream(stats)
                .filter(Objects::nonNull)
                .mapToLong(MessageQueue.QueueStats::getFailedCount)
                .sum();
        long totalOperations = totalProcessed + totalFailed;
        double overallSuccessRate = totalOperations > 0 ?
                (double) totalProcessed / totalOperations * 100 : 100.0;

        System.out.printf("总消息数: %d, 总处理: %d, 总失败: %d, 总体成功率: %.2f%%%n",
                totalMessages, totalProcessed, totalFailed, overallSuccessRate);
        System.out.println("===============================================");
    }

    /**
     * 打印队列负载报告（中文版）
     */
    public static void printLoadReport() {
        System.out.println("=== 队列负载报告 ===");
        System.out.println("报告时间: " + LocalDateTime.now().format(FORMATTER));
        System.out.println("--------------------------------------------------");

        MessageQueue.QueueStats[] stats = MQToolkit.getAllQueueStats();
        if (stats == null || stats.length == 0) {
            System.out.println("未找到任何队列。");
            return;
        }

        System.out.printf("%-20s | %-10s | %-10s | %-10s%n",
                "队列名称", "消息积压", "消费者数", "负载状态");
        System.out.println("--------------------------------------------------");

        Arrays.stream(stats).forEach(stat -> {
            if (stat != null) {
                long messageCount = stat.getMessageCount();
                int consumerCount = stat.getConsumerCount();
                String loadStatus;

                if (consumerCount == 0) {
                    loadStatus = "无消费者";
                } else {
                    double ratio = (double) messageCount / consumerCount;
                    if (ratio > 1000) {
                        loadStatus = "高负载";
                    } else if (ratio > 100) {
                        loadStatus = "中负载";
                    } else if (ratio > 10) {
                        loadStatus = "低负载";
                    } else {
                        loadStatus = "负载正常";
                    }
                }

                System.out.printf("%-20s | %-10d | %-10d | %-10s%n",
                        stat.getQueueName(),
                        messageCount,
                        consumerCount,
                        loadStatus);
            }
        });

        System.out.println("===============================================");
    }
}